package conversion.utils.converter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.opencsv.CSVWriter;
import org.yaml.snakeyaml.Yaml;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import java.io.IOException;


/**
 * YamlProcessor 类用于处理YAML字符串，提供转换等操作。
 * @author ZJW
 * 版本：1.0
 */
public class YamlProcessor {

    /**
     * 验证yaml格式是否正确
     *
     * @param yaml 要验证的yaml字符串
     * @return 格式正确返回ture，否则返回false
     */
    public static boolean isFormatValid(String yaml) {
        try {
            Yaml yamlParser = new Yaml();
            yamlParser.load(yaml);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 给指定的yaml字符串转换成csv字符串
     *
     * @param yamlString 要转换的yaml字符串
     * @return 返回csv字符串
     */
    public static String convertToCSV(String yamlString) throws IOException {

        // 创建Yaml对象并用其解析YAML字符串，将数据载入列表中。
        Yaml yaml = new Yaml();
        List<Map<String, String>> dataList = yaml.load(yamlString);

        // 从第一行数据提取标题行。
        String[] headers = dataList.get(0).keySet().toArray(new String[0]);

        // 创建一个StringWriter和CSVWriter对象，将CSV数据写入StringWriter。
        StringWriter stringWriter = new StringWriter();
        CSVWriter csvWriter = new CSVWriter(stringWriter);

        // 将标题行写入CSV文件。
        csvWriter.writeNext(headers);

        // 遍历数据行并将其写入CSV文件。
        for (Map<String, String> row : dataList) {
            String[] rowData = new String[headers.length];
            for (int i = 0; i < headers.length; i++) {
                String header = headers[i];
                String value = row.get(header);
                rowData[i] = value != null ? value : "";
            }
            csvWriter.writeNext(rowData);
        }
        // 关闭CSVWriter并返回转换后的CSV字符串
        csvWriter.close();

        return stringWriter.toString();

    }


    /**
     * 将YAML字符串转换成JSON字符串
     * @param yamlString 要转换的YAML字符串
     * @return 转换后的JSON字符串，如果转换失败则返回null
     */
    public static String convertToJSON(String yamlString) throws JsonProcessingException {

        // 创建一个用于解析YAML的ObjectMapper
        ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());

        // 读取YAML字符串并转换为JSON树
        JsonNode rootNode = yamlMapper.readTree(yamlString);

        // 创建一个ObjectMapper用于写JSON，并启用缩进
        ObjectMapper jsonMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);

        // 将JSON树转换为JSON字符串
        return jsonMapper.writeValueAsString(rootNode);

    }

    /**
     * 将YAML字符串转换为XML字符串。
     *
     * @param yamlString YAML格式的字符串
     * @return XML格式的字符串
     * @throws Exception 转换异常
     */
    public static String convertToXML(String yamlString) throws Exception {
        // 创建一个XmlMapper对象，用于将YAML字符串转换为XML字符串
        XmlMapper xmlMapper = new XmlMapper();

        // 创建一个ObjectMapper对象，用于将YAML字符串转换为Java对象
        YAMLFactory yamlFactory = new YAMLFactory();
        com.fasterxml.jackson.databind.ObjectMapper yamlReader = new com.fasterxml.jackson.databind.ObjectMapper(yamlFactory);

        // 将YAML字符串转换为Java对象
        Object obj = yamlReader.readValue(yamlString, Object.class);

        // 将Java对象转换为XML字符串
        return xmlMapper.writeValueAsString(obj);
    }


    public static String enhancedConvertToYAML(String yamlString) throws Exception {
        // 创建一个ObjectMapper对象，用于将YAML字符串转换为Java对象
        ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory());

        // 将YAML字符串转换为Java对象
        Map<String, Object> yamlObj = yamlReader.readValue(yamlString, Map.class);

        // 将Java对象转换为CSV字符串
        List<String> csvLines = new ArrayList<>();
        flattenYaml("", yamlObj, csvLines);

        return String.join("\n", csvLines);
    }

    private static void flattenYaml(String prefix, Map<String, Object> yamlObj, List<String> csvLines) {
        for (Map.Entry<String, Object> entry : yamlObj.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (value instanceof Map) {
                // 处理嵌套的Map对象
                flattenYaml(prefix + key + ".", (Map<String, Object>) value, csvLines);
            } else if (value instanceof List) {
                // 处理列表对象
                flattenList(prefix + key, (List<Object>) value, csvLines);
            } else {
                // 处理单个属性值
                csvLines.add(prefix + key + "," + value);
            }
        }
    }

    private static void flattenList(String prefix, List<Object> list, List<String> csvLines) {
        for (int i = 0; i < list.size(); i++) {
            Object value = list.get(i);

            if (value instanceof Map) {
                // 处理嵌套的Map对象
                flattenYaml(prefix + "[" + i + "].", (Map<String, Object>) value, csvLines);
            } else if (value instanceof List) {
                // 处理嵌套的列表对象
                flattenList(prefix + "[" + i + "]", (List<Object>) value, csvLines);
            } else {
                // 处理单个属性值
                csvLines.add(prefix + "[" + i + "]" + "," + value);
            }
        }
    }
}
